﻿using Abp.Collections.Extensions;
using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.ObjectMapping;
using Mt.Site.Core.WorkFlows.Design;
using Mt.Site.Core.WorkFlows.Design.Entities;
using Mt.Site.Core.WorkFlows.Process.Entities;
using Mt.Site.Core.WorkFlows.Process.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Mt.Site.Core.WorkFlows.Process.Impl
{
    public class WorkFlowHelper : IWorkFlowHelper, ITransientDependency
    {
        public IWorkFlowFactory WorkFlowFactory { get; private set; }
        private readonly IRepository<WorkFlowPaper, Guid> _workFlowPaperRepository;
        private readonly IRepository<WorkFlow, Guid> _workFlowRepository;

        public IObjectMapper ObjectMapper { get; set; }

        public WorkFlowHelper(
            IWorkFlowFactory workFlowFactory,
            IRepository<WorkFlow, Guid> workFlowRepository,
            IRepository<WorkFlowPaper, Guid> workFlowPaperRepository)
        {
            WorkFlowFactory = workFlowFactory;
            _workFlowRepository = workFlowRepository;
            _workFlowPaperRepository = workFlowPaperRepository;

            ObjectMapper = NullObjectMapper.Instance;
        }

        public async Task<WorkFlowPaper> FirstOrDefaultWorkFlowPaperAsync(Guid paperId)
        {
            return await _workFlowPaperRepository.FirstOrDefaultAsync(paperId);
        }

        public async Task<WorkFlowPaper> GetWorkFlowPaperAsync(Guid paperId)
        {
            return await _workFlowPaperRepository.GetAsync(paperId);
        }

        public async Task<List<WorkFlowPaperDto>> GetAllWorkFlowPaperAsync(Expression<Func<WorkFlowPaper, bool>> predicate)
        {
            var list = await _workFlowPaperRepository.GetAllListAsync(predicate);
            return ObjectMapper.Map<List<WorkFlowPaperDto>>(list);
        }

        public List<WorkFlowPaperDto> GetAllWorkFlowPaper(Expression<Func<WorkFlowPaper, bool>> predicate)
        {
            var list = _workFlowPaperRepository.GetAllList(predicate);
            return ObjectMapper.Map<List<WorkFlowPaperDto>>(list);
        }

        public async Task<string> GetWenhaoAsync(Guid paperId, Guid workFlowId)
        {
            var paper = await _workFlowPaperRepository.GetAsync(paperId);
            if (!paper.ReferNumber.IsNullOrWhiteSpace())
            {
                return paper.ReferNumber;
            }

            var workFlow = await _workFlowRepository.GetAsync(workFlowId);

            var numStr = (workFlow.NumberCounting + 1).ToString();
            if (numStr.Length < workFlow.DigitNumber)
            {
                numStr = string.Join("", Enumerable.Repeat('0', workFlow.DigitNumber - numStr.Length)) + numStr;
            }

            var result = workFlow.NumberFormat;
            if (result.IsNullOrEmpty())
            {
                result = numStr;
            }
            else
            {
                var now = DateTime.Now;
                result = result.Replace("{年}", now.Year.ToString());                //年
                result = result.Replace("{月}", now.ToString("MM"));                 //月
                result = result.Replace("{日}", now.ToString("dd"));                 //日
                result = result.Replace("{时}", now.ToString("HH"));                 //时
                result = result.Replace("{分}", now.ToString("mm"));                 //分
                result = result.Replace("{秒}", now.ToString("ss"));                 //秒

                result = result.Replace("{流程名}", workFlow.Name);                    //流程名
                result = result.Replace("{流程简称}", workFlow.ShortName);             //流程简称
                result = result.Replace("{用户姓名}", paper.UserName);                 //用户姓名
                result = result.Replace("{发文部门}", paper.UnitName);                 //发文部门
                result = result.Replace("{流水号}", paper.SerialNumber.ToString());    //流水号
                result = result.Replace("{编号}", numStr);                             //编号
                result = result.Trim();
            }
            workFlow.NumberCounting = workFlow.NumberCounting + 1;
            paper.ChangeReferNumber(result);

            return result;
        }

        public async Task<string> GetDefautTitle(Guid workFlowId)
        {
            var workFlow = await WorkFlowFactory.GetWorkflowDefinitionAsync(workFlowId);
            var workFlowDef = workFlow.Definition;
            var result = workFlowDef.CustomData?.DefaultTitleFormat;
            if (!result.IsNullOrWhiteSpace())
            {
                result = result.Trim();
            }
            else
            {
                result = workFlowDef.Name + "({年}-{月}-{日} {时}:{分}:{秒})";
            }
            return result;
        }
    }
}
